package com.tengju.bff.interfaces.covercharge.util;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.beust.jcommander.internal.Lists;
import com.tengju.activity.domain.shared.CastUtil;
import com.tengju.bff.interfaces.shared.AmountVO;
import com.tengju.bff.interfaces.shared.ColumnVO;
import com.tengju.bff.interfaces.shared.TableVO;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class CsvExportUtil {

    /**
     * CSV文件列分隔符
     */
    private static final String CSV_COLUMN_SEPARATOR = ",";

    /**
     * CSV文件行分隔符
     */
    private static final String CSV_ROW_SEPARATOR = "\r\n";

    /**
     * @param dataList 集合数据
     * @param titles   表头部数据
     * @param keys     表内容的键值
     * @param os       输出流
     */
    public static void doExport(List<Map<String, Object>> dataList, String titles, String keys, OutputStream os) throws Exception {

        // 保证线程安全
        StringBuffer buf = new StringBuffer();

        String[] titleArr = null;
        String[] keyArr = null;

        titleArr = titles.split(",");
        keyArr = keys.split(",");

        // 组装表头
        for (String title : titleArr) {
            buf.append(title).append(CSV_COLUMN_SEPARATOR);
        }
        buf.append(CSV_ROW_SEPARATOR);

        // 组装数据
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (Map<String, Object> data : dataList) {
                for (String key : keyArr) {
                    buf.append(data.get(key)).append(CSV_COLUMN_SEPARATOR);
                }
                buf.append(CSV_ROW_SEPARATOR);
            }
        }

        // 写出响应
        os.write(buf.toString().getBytes("GBK"));
        os.flush();
    }

    /**
     * @param tableVO 表格数据
     * @param os      输出流
     */
    public static void doExport(TableVO tableVO, OutputStream os) throws Exception {
        try {
            // 保证线程安全
            StringBuffer buf = new StringBuffer();

            List<String> titles = Optional.ofNullable(tableVO)
                    .map(TableVO::getHeader)
                    .map(h -> h.stream().map(ColumnVO::getLabel)
                            .collect(Collectors.toList()))
                    .orElse(Lists.newArrayList());

            List<String> keys = Optional.ofNullable(tableVO)
                    .map(TableVO::getHeader)
                    .map(h -> h.stream().map(ColumnVO::getProp)
                            .collect(Collectors.toList()))
                    .orElse(Lists.newArrayList());

            List<Map<String, Object>> records = Optional.ofNullable(tableVO)
                    .map(TableVO::getRecords)
                    .orElse(Lists.newArrayList());

            // 组装表头
            for (String title : titles) {
                buf.append(title).append(CSV_COLUMN_SEPARATOR);
            }
            buf.append(CSV_ROW_SEPARATOR);

            // 组装数据
            if (CollectionUtils.isNotEmpty(records)) {
                for (Map<String, Object> data : records) {
                    for (String key : keys) {
                        Object val = data.get(key);
                        if (val instanceof AmountVO){
                            buf.append(((AmountVO) val).getValue()
                                    .concat(" ")
                                    .concat(CastUtil.castString(((AmountVO) val).getDesc()))
                                    .replace(",", ""))
                                    .append(CSV_COLUMN_SEPARATOR);
                        } else {
                            buf.append((val + "").replace(",", "")).append(CSV_COLUMN_SEPARATOR);
                        }
                    }
                    buf.append(CSV_ROW_SEPARATOR);
                }
            }

            // 写出响应
            os.write(buf.toString().getBytes("GBK"));
            os.flush();
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }


    /**
     * 设置Header
     *
     * @param fileName
     * @param response
     * @throws UnsupportedEncodingException
     */
    public static void responseSetProperties(String fileName, HttpServletRequest request, HttpServletResponse response) {
        // 设置文件后缀
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fn = fileName + sdf.format(new Date()) + ".csv";
        // 读取字符编码
        String utf = "UTF-8";
        fn = getFileName(request,response,fn);

        // 设置响应
//        response.setContentType("application/csv;charset=gbk");
//        response.setCharacterEncoding(utf);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition", processFileName(request,fileName));
        response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
    }

    public static String processFileName(HttpServletRequest request, String fileName) {
        String userAgent = request.getHeader("User-Agent").toLowerCase();
        //chrome头也包含safari,需要排除chrome
        if(userAgent.contains("safari") && !userAgent.contains("chrome")){
            //处理safari的乱码问题
            byte[] bytesName = fileName.getBytes(Charset.forName("UTF-8"));
            fileName = new String(bytesName, Charset.forName("ISO-8859-1"));
            return "attachment;fileName="+ fileName + ".csv";
        }else {
            try {
                return "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8") + ".csv";
            } catch (Throwable e) {
            }
        }
        return null;
    }

    public static String getFileName(HttpServletRequest request, HttpServletResponse response, String fileName) {
        final String userAgent = request.getHeader("USER-AGENT");
        String finalFileName = null;
        try {
            if (StringUtils.contains(userAgent, "MSIE")) {
                // IE浏览器
                finalFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
            } else if (StringUtils.contains(userAgent, "Mozilla")) {
                // google,火狐浏览器
                finalFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
            } else {
                finalFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
            }
        } catch (UnsupportedEncodingException e) {
        }
        return finalFileName;
    }

}